import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.GregorianCalendar;

import javax.xml.bind.ParseConversionEvent;
import javax.xml.ws.http.HTTPException;

import com.sun.net.httpserver.*;

public class Server {
	static DatabaseConnection db = null;
	
	static class GetAllHandler implements HttpHandler {

		@SuppressWarnings("restriction")
		@Override
		public void handle(HttpExchange arg0) throws IOException {
			BufferedOutputStream returnContent = new BufferedOutputStream(arg0.getResponseBody());
			
			String resp = parseCommand();
			byte[] bytes = resp.getBytes("UTF8");
			
			arg0.getResponseHeaders().set("content-type", "application/xml");
			arg0.sendResponseHeaders(206, bytes.length);
			returnContent.write(bytes);
			returnContent.close();
		}
		
		private String parseCommand() {
			String outputXML = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
			
			outputXML += "<ticketview>\n";
				
			for (TicketQueue k : db.getAllTickets()) {
				outputXML += "<queue>\n";
				outputXML += "<id>"+k.getId()+"</id>\n";
				outputXML += "<code>"+k.getCode()+"</code>\n";
				outputXML += "<description>"+k.getName()+"</description>\n";
				outputXML += "<currentTicket>"+k.getCurrentTicket()+"</currentTicket>\n";
				outputXML += "<desk>"+k.getDesk()+"</desk>\n";
				outputXML += "</queue>\n";
			}
			outputXML += "</ticketview>";
		
			return outputXML;
		}
	}

	static class GetByServiceHandler implements HttpHandler {
		
		
		public void handle(HttpExchange arg0) throws IOException {
			BufferedOutputStream returnContent = new BufferedOutputStream(arg0.getResponseBody());
			
			String query = arg0.getRequestURI().getQuery();
			Map<String, String> queryVariables = extractData(query);
			
			
			String resp = parseCommand(queryVariables.get("idService"));
			byte[] bytes = resp.getBytes("UTF8");
			
			arg0.getResponseHeaders().set("content-type", "application/xml");
			arg0.sendResponseHeaders(206, bytes.length);
			returnContent.write(bytes);
			returnContent.close();
		}
		
		private String parseCommand(String idService) {			
			String outputXML = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
			
			outputXML += "<ticketview>\n";
			outputXML += "<service>\n";
			outputXML += "<id>" + idService + "</id>\n";
			outputXML += "<code>"+ db.getCode(idService) +"</code>\n";
			
			String[] ticketInformation = db.getLastTicketPrinted(idService);
			String[] ticketServed = db.getLastTicketServed(idService);

			if (ticketServed != null) {
			outputXML += "<ticketServedNumber>" + ticketServed[0] + "</ticketServedNumber>\n";
			outputXML += "<ticketServedHour>" + ticketServed[2] + "</ticketServedHour>\n";
			outputXML += "<desk>" + ticketServed[1] + "</desk>\n";

			}
			else {
				outputXML += "<ticketServedNumber>null</ticketServedNumber>\n";
				outputXML += "<ticketServedHour>null</ticketServedHour>\n";
				outputXML += "<desk>null</desk>\n";
			}
			
			if (ticketInformation != null) {
				outputXML += "<lastTicketPrintedNumber>" + ticketInformation[0] + "</lastTicketPrintedNumber>\n";
				outputXML += "<lastTicketPrintedHour>" + ticketInformation[1] + "</lastTicketPrintedHour>\n"; 
				outputXML += "<expectedTime>" + addMinutesToTime(ticketInformation[1], ticketInformation[2]) + "</expectedTime>\n";
			}
			else {
				outputXML += "<lastTicketPrintedNumber>null</lastTicketPrintedNumber>\n";
				outputXML += "<lastTicketPrintedHour>null</lastTicketPrintedHour>\n"; 
				outputXML += "<expectedTime>null</expectedTime>\n";
			}
			
			outputXML += "<remainingTickets>" + db.getRemainingTickets(idService) + "</remainingTickets>\n";
			outputXML += "<allRemainingTickets>" + db.getAllRemainingTickets() + "</allRemainingTickets>\n";
			outputXML += "</service></ticketview>";

			return outputXML;
		}
		
		private String addMinutesToTime(String originalTime, String minutesToAdd) {
			System.out.println("originalTime: " + originalTime);
			System.out.println("minutos: " + minutesToAdd);
			
			// Formato da string originalTime: 15:08:00
			int hours = Integer.parseInt(originalTime.substring(0, 2));
			int minutes = Integer.parseInt(originalTime.substring(3, 5));
			
			Calendar originalCalendar = new GregorianCalendar();
			
			originalCalendar.set(Calendar.HOUR_OF_DAY, hours);
			originalCalendar.set(Calendar.MINUTE, minutes);
			
			originalCalendar.add(Calendar.MINUTE, Integer.parseInt(minutesToAdd));
			
			return originalCalendar.get(Calendar.HOUR_OF_DAY) + ":" + originalCalendar.get(Calendar.MINUTE) + ":" + originalTime.substring(6);
		}

		private Map<String, String> extractData(String query) {
			HashMap<String, String> data = new HashMap<String, String>();
			
			for (String variable: query.split("&")) {
				String temp[] = variable.split("=");
				data.put(temp[0], temp[1]);
			}
			return data;
		}
		
		// TODO: Fazer o isValidRequest
	}
	
	/**
	 * @param args
	 */
	@SuppressWarnings("restriction")
	public static void main(String args[]) throws UnknownHostException, IOException {
		HttpServer server = HttpServer.create(new InetSocketAddress(InetAddress
						.getByName("localhost"), 8080), 6);

		Scanner leitor = new Scanner(System.in);
		
		System.out.print("Username: ");
		String username = leitor.nextLine();
		
		System.out.print("Password: ");
		String password = leitor.nextLine();

		
		db = new DatabaseConnection(username, password);
		server.createContext("/GETALL", new GetAllHandler());
		server.createContext("/GETBYSERVICE", new GetByServiceHandler());

		server.start();
	}
}
